<template>
  <div class="hello">
    <!-- <el-button @click="exportToExcel">导出Excel</el-button> -->
    <div ref="container"></div>
  </div>
</template>

<script setup>
import { onMounted, ref } from "vue";
//   import { message } from 'ant-design-vue';
import {
  PivotSheet,
  DataCell,
  RowCell,
  ColCell,
  S2Theme,
  FONT_FAMILY,
  CellTextWordWrapStyle,
  getCellMeta,
  renderText,
} from "@antv/s2";
import { Image as GImage, Group, Text } from "@antv/g";
// import "@antv/s2-vue/dist/s2-vue.min.css";

const customTree = [
  {
    field: "a-1",
    title:
      "财政教育经费投入收到捡垃圾几点几分解决法鸡打两局基督教啊了解倒垃圾阿斯顿发束带结发垃圾袋反垃圾飞拉达较大发啦代发发的三到付件拉法基到啦的",
    width: 120,
    height: 60,
    wordTR: "vl",
    children: [
      {
        field: "a-1-1",
        title: "项目经费",
        width: 60,
        children: [
          {
            field: "bzhjs",
            width: 30,
            title: "标准化建设标准",
            children: [],
          },
          {
            field: "xxhjs",
            width: 30,
            title: "信息化建设",
            children: [],
          },
        ],
      },
      {
        field: "a-1-2",
        title: "基础拨款",
        width: 30,
        children: [],
      },
    ],
  },
  {
    field: "a-2",
    title: "其他投入",
    children: [],
  },
  {
    field: "a-1-1",
    title: "项目经费",
    // width: 50,
    children: [
      {
        field: "bzhjs",
        title: "标准化建设标准",
       width:50,
        children: [],
      },
      {
        field: "xxhjs",
        title: "信息化建设",
        // height:300,
        width:50,
        children: [],
      },
    ],
  },
];

// 定义省市县的自定义树形结构

const rowsTreeHierarchy = [
  {
    field: "hz",
    title: "汇总",
    wordTR: "vl",
    width: 180,
    height: 30,
    level: 1,
    description: "汇总",
  },
  {
    field: "beijing",
    title: "北京市",
    wordTR: "vl",
    width: 30,
    height: 30,
    level: 1,
    description: "北京省描述",
    children: [
      {
        field: "fz",
        title: "分计sdfsfdjsaldj",
        wordTR: "vl",
        width: 40,
        level: 2,
        height: 30,
        description: "分计",
        children: [],
      },
      {
        field: "haidian",
        title: "海淀区秒的的按到",
        wordTR: "vl",
        width: 80,
        height: 30,
        level: 2,
        description: "海淀区描述",
        children: [
          {
            field: "zizhuyuan",
            title: "紫竹院",
            width: 120,
            height: 30,
            level: 3,
            description: "紫竹院描述",
            children: [],
          },
          {
            field: "zhongguancun",
            title: "中关村",
            width: 120,
            height: 60,
            level: 3,
            description: "中关村描述",
            children: [],
          },
        ],
      },
    ],
  },
  {
    field: "shanghai",
    title: "上海市上海市上海市上海市上海市上海市",
    width: 100,
    height: 30,
    level: 1,
    description: "上海省描述",
    children: [
      {
        field: "huangpu",
        title: "黄浦区军校区域手动阀代发费撒打发啊",
        level: 2,
        height: 60,
        description: "黄浦区描述",
        children: [],
      },
    ],
  },
];

class CustomDataCell extends DataCell {
  getFieldValue() {
    // 获取行 ID 和列 ID
    const { x, y, rowId, colId } = this.getMeta();
    // console.log(x,y,rowId,colId,'---------')
    // 分割 `rowId` 和 `colId` 获取具体字段
    const rowFields = rowId.split("[&]").slice(1); // 跳过 'root'
    const colFields = colId.split("[&]").slice(1); // 跳过 'root'

    // 遍历 `displayData` 查找匹配的记录
    const data = this.spreadsheet.dataSet.displayData;
    const valuesField = this.spreadsheet.dataSet.fields.values[0]; // 获取 'value' 字段

    let value = null;
    for (const item of data) {
      // 判断 `rowFields` 和 `colFields` 是否都匹配
      const isRowMatch = rowFields.every((field) => item[field] !== undefined);
      const isColMatch = colFields.every((field) => item[field] !== undefined);

      if (isRowMatch && isColMatch) {
        value = item[valuesField]; // 获取数据值
        break;
      }
    }
    return value;
  }
}

// class CustomRowCell extends RowCell {
//   drawTextShape() {
//     const { x, y, width, height, value } = this.getMeta();
//     const text = String(value || ""); // 单元格文本内容
//     if (this.meta.extra.writingMode === "ls") {
//       const textStyle = {
//         fontSize: 12,
//         fill: "#000",
//         textAlign: "left",
//         textBaseline: "top",
//       };
//       const padding = 10; // 单元格左右内边距
//       const textHeight = textStyle.fontSize; // 每个字符的宽度
//       const lineSpacing = 0; // 行间距
//       const lineWidth = 1.5 * textHeight + lineSpacing; // 行宽
//       const centerX = x + width / 2 - lineWidth / 2; // X 坐标居中
//       const baseY = y + padding; // 起始 X 坐标
//       // 计算每行可以放置的最大字符数
//       const count = Math.floor((height - padding * 2) / textHeight);
//       console.log(count, "最大展示的字数");
//       let currentX = centerX; // 初始化 x 坐标以保证第一行居中显示
//       let charIndex = 0; //
//       let lines = [];

//       // 第一次遍历：分割文本成多行，并收集每一行的文本
//       while (charIndex < text.length) {
//         let lineText = "";
//         for (
//           let i = 0;
//           i < count && charIndex < text.length;
//           i++, charIndex++
//         ) {
//           lineText += text[charIndex];
//         }
//         lines.push(lineText);
//       }
//       console.log(lines, "===========lines=======");
//       // 渲染每一行文本
//       lines.forEach((lineText, lineIndex) => {
//         if (
//           lineIndex === lines.length - 1 &&
//           lineText.length > 1 &&
//           lines.length > 1
//         ) {
//           // 最后一行且不止一个字符
//           // 分散对齐最后一行字符
//           const spacing =
//             (height - 2 * padding - textHeight * lineText.length) /
//             (lineText.length - 1);
//           [...lineText].forEach((char, index) => {
//             const charY = baseY + index * (textHeight + spacing);
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 x: currentX,
//                 y: charY,
//                 text: `${char}`,
//               },
//             });
//           });
//         } else if (lines.length === 1) {
//           //只有一行时
//           const spacing =
//             (height - 2 * padding - textHeight * lineText.length) /
//             (lineText.length - 1);
//           [...lineText].forEach((char, index) => {
//             const charY = baseY + index * (spacing + textHeight);
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 y: charY,
//                 x: x + width / 2,
//                 text: `${char}`,
//               },
//             });
//           });
//         } else {
//           // 正常渲染其他行文本
//           [...lineText].forEach((char, index) => {
//             const charY = baseY + index * textHeight;
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 y: charY,
//                 x: currentX,
//                 text: `${char}`,
//               },
//             });
//           });
//         }
//         this.addTextShape(this.textShape);

//         // 更新到下一行的 Y 坐标
//         // 这里是从左到右的排列顺序
//         currentX += lineWidth;
//         // 这里是从右到左的排列顺序
//         // currentX -= lineWidth;
//       });
//     } else {
//       const textStyle = {
//         fontSize: 12,
//         fill: "#000",
//         textAlign: "left",
//         textBaseline: "middle",
//       };
//       const padding = 10; // 单元格左右内边距
//       const textWidth = textStyle.fontSize; // 每个字符的宽度
//       const lineSpacing = 0; // 行间距
//       const lineHeight = 1.5 * textWidth + lineSpacing; // 行高
//       const baseX = x + padding; // 起始 X 坐标
//       const centerY = y + height / 2 - lineHeight / 2; // Y 坐标居中

//       // 计算每行可以放置的最大字符数
//       const count = Math.floor((width - padding * 2) / textWidth);

//       let currentY = centerY; // 初始化 Y 坐标以保证第一行居中显示
//       let charIndex = 0;
//       let lines = [];

//       // 第一次遍历：分割文本成多行，并收集每一行的文本
//       while (charIndex < text.length) {
//         let lineText = "";
//         for (
//           let i = 0;
//           i < count && charIndex < text.length;
//           i++, charIndex++
//         ) {
//           lineText += text[charIndex];
//         }
//         lines.push(lineText);
//       }

//       // 渲染每一行文本
//       lines.forEach((lineText, lineIndex) => {
//         if (
//           lineIndex === lines.length - 1 &&
//           lineText.length > 1 &&
//           lines.length > 1
//         ) {
//           // 最后一行且不止一个字符
//           // 分散对齐最后一行字符
//           const spacing =
//             (width - 2 * padding - textWidth * lineText.length) /
//             (lineText.length - 1);
//           [...lineText].forEach((char, index) => {
//             const charX = baseX + index * (textWidth + spacing);
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 x: charX,
//                 y: currentY,
//                 text: `${char}`,
//               },
//             });
//           });
//         } else if (lines.length === 1) {
//           //只有一行时
//           const spacing =
//             (width - 2 * padding - textWidth * lineText.length) /
//             (lineText.length - 1);
//           [...lineText].forEach((char, index) => {
//             const charX = baseX + index * (textWidth + spacing);
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 x: charX,
//                 y: y + height / 2,
//                 text: `${char}`,
//               },
//             });
//           });
//         } else {
//           // 正常渲染其他行文本
//           [...lineText].forEach((char, index) => {
//             const charX = baseX + index * textWidth;
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 x: charX,
//                 y: currentY,
//                 text: `${char}`,
//               },
//             });
//           });
//         }
//         this.addTextShape(this.textShape);

//         // 更新到下一行的 Y 坐标
//         currentY += lineHeight;
//       });
//     }

//     console.log(this.textShapes);
//   }
// }

// class CustomColCell extends ColCell {
//   drawTextShape() {
//     const { x, y, width, height, value } = this.getMeta();
//     const text = String(value || ""); // 单元格文本内容
//     if (this.meta.extra.writingMode === "ls") {
//       const textStyle = {
//         fontSize: 12,
//         fill: "#000",
//         textAlign: "left",
//         textBaseline: "top",
//       };
//       const padding = 10; // 单元格左右内边距
//       const textHeight = textStyle.fontSize; // 每个字符的宽度
//       const lineSpacing = 0; // 行间距
//       const lineWidth = 1.5 * textHeight + lineSpacing; // 行宽
//       const centerX = x + width / 2 - lineWidth / 2; // X 坐标居中
//       const baseY = y + padding; // 起始 X 坐标
//       // 计算每行可以放置的最大字符数
//       const count = Math.floor((height - padding * 2) / textHeight);
//       console.log(count, "最大展示的字数");
//       let currentX = centerX; // 初始化 x 坐标以保证第一行居中显示
//       let charIndex = 0; //
//       let lines = [];

//       // 第一次遍历：分割文本成多行，并收集每一行的文本
//       while (charIndex < text.length) {
//         let lineText = "";
//         for (
//           let i = 0;
//           i < count && charIndex < text.length;
//           i++, charIndex++
//         ) {
//           lineText += text[charIndex];
//         }
//         lines.push(lineText);
//       }
//       console.log(lines, "===========lines=======");
//       // 渲染每一行文本
//       lines.forEach((lineText, lineIndex) => {
//         if (
//           lineIndex === lines.length - 1 &&
//           lineText.length > 1 &&
//           lines.length > 1
//         ) {
//           // 最后一行且不止一个字符
//           // 分散对齐最后一行字符
//           const spacing =
//             (height - 2 * padding - textHeight * lineText.length) /
//             (lineText.length - 1);
//           [...lineText].forEach((char, index) => {
//             const charY = baseY + index * (textHeight + spacing);
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 x: currentX,
//                 y: charY,
//                 text: `${char}`,
//               },
//             });
//           });
//         } else if (lines.length === 1) {
//           //只有一行时
//           const spacing =
//             (height - 2 * padding - textHeight * lineText.length) /
//             (lineText.length - 1);
//           [...lineText].forEach((char, index) => {
//             const charY = baseY + index * (spacing + textHeight);
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 y: charY,
//                 x: x + width / 2,
//                 text: `${char}`,
//               },
//             });
//           });
//         } else {
//           // 正常渲染其他行文本
//           [...lineText].forEach((char, index) => {
//             const charY = baseY + index * textHeight;
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 y: charY,
//                 x: currentX,
//                 text: `${char}`,
//               },
//             });
//           });
//         }
//         this.addTextShape(this.textShape);

//         // 更新到下一行的 Y 坐标
//         // 这里是从左到右的排列顺序
//         currentX += lineWidth;
//         // 这里是从右到左的排列顺序
//         // currentX -= lineWidth;
//       });
//     } else {
//       const textStyle = {
//         fontSize: 12,
//         fill: "#000",
//         textAlign: "left",
//         textBaseline: "middle",
//       };
//       const padding = 10; // 单元格左右内边距
//       const textWidth = textStyle.fontSize; // 每个字符的宽度
//       const lineSpacing = 0; // 行间距
//       const lineHeight = 1.5 * textWidth + lineSpacing; // 行高
//       const baseX = x + padding; // 起始 X 坐标
//       const centerY = y + height / 2 - lineHeight / 2; // Y 坐标居中

//       // 计算每行可以放置的最大字符数
//       const count = Math.floor((width - padding * 2) / textWidth);

//       let currentY = centerY; // 初始化 Y 坐标以保证第一行居中显示
//       let charIndex = 0;
//       let lines = [];

//       // 第一次遍历：分割文本成多行，并收集每一行的文本
//       while (charIndex < text.length) {
//         let lineText = "";
//         for (
//           let i = 0;
//           i < count && charIndex < text.length;
//           i++, charIndex++
//         ) {
//           lineText += text[charIndex];
//         }
//         lines.push(lineText);
//       }

//       // 渲染每一行文本
//       lines.forEach((lineText, lineIndex) => {
//         if (
//           lineIndex === lines.length - 1 &&
//           lineText.length > 1 &&
//           lines.length > 1
//         ) {
//           // 最后一行且不止一个字符
//           // 分散对齐最后一行字符
//           const spacing =
//             (width - 2 * padding - textWidth * lineText.length) /
//             (lineText.length - 1);
//           [...lineText].forEach((char, index) => {
//             const charX = baseX + index * (textWidth + spacing);
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 x: charX,
//                 y: currentY,
//                 text: `${char}`,
//               },
//             });
//           });
//         } else if (lines.length === 1) {
//           //只有一行时
//           const spacing =
//             (width - 2 * padding - textWidth * lineText.length) /
//             (lineText.length - 1);
//           [...lineText].forEach((char, index) => {
//             const charX = baseX + index * (textWidth + spacing);
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 x: charX,
//                 y: y + height / 2,
//                 text: `${char}`,
//               },
//             });
//           });
//         } else {
//           // 正常渲染其他行文本
//           [...lineText].forEach((char, index) => {
//             const charX = baseX + index * textWidth;
//             this.textShape = renderText({
//               group: this,
//               textShape: [this.textShape],
//               style: {
//                 ...textStyle,
//                 x: charX,
//                 y: currentY,
//                 text: `${char}`,
//               },
//             });
//           });
//         }
//         this.addTextShape(this.textShape);

//         // 更新到下一行的 Y 坐标
//         currentY += lineHeight;
//       });
//     }

//     console.log(this.textShapes);
//   }
// }

// 工具函数：文本分行逻辑

const splitTextIntoLines = (text, maxWidth, charWidth) => {
  const lines = [];
  let currentLine = "";

  [...text].forEach((char) => {
    const tempLine = currentLine + char;
    if (tempLine.length * charWidth > maxWidth) {
      lines.push(currentLine);
      currentLine = char;
    } else {
      currentLine = tempLine;
    }
  });
  if (currentLine) lines.push(currentLine);
  return lines;
  // 计算每行可以放置的最大字符数
  // console.log(maxWidth,charWidth,'---------------------')
  // const count = Math.floor(maxWidth / charWidth);
  // console.log(count, "最大展示的字数");
  // let charIndex = 0; //
  // let lines = [];

  // // 第一次遍历：分割文本成多行，并收集每一行的文本
  // while (charIndex < text.length) {
  //   let lineText = "";
  //   for (let i = 0; i < count && charIndex < text.length; i++, charIndex++) {
  //     lineText += text[charIndex];
  //   }
  //   lines.push(lineText);
  // }
};

// 工具函数：计算动态行高
const calculateHeaderRowHeight = (viewMeta) => {
  const fontSize = 12,
    padding = 8,
    lineHeight = 14;
  const lines = splitTextIntoLines(
    viewMeta.value || "",
    viewMeta.width - 2 * padding,
    fontSize
  );
  return lines.length * lineHeight + padding * 2;
};

const calculateHeaderColWidth = (viewMeta) => {
  return headerColWidths[viewMeta.field];
};

// 获取树形数据的最大层级
const getMaxLevel = (tree) => {
  let maxLevel = 0;

  function traverse(node) {
    if (node.level > maxLevel) maxLevel = node.level;
    if (node.children && node.children.length > 0) {
      node.children.forEach(traverse);
    }
  }

  tree.forEach(traverse);
  return maxLevel;
};

/**
 * 计算表旁每列宽度
 * @param {Array} tree - 树形结构
 * @returns {Array} - 每列宽度
 */
const calculateSideColumnWidths = (tree) => {
  const maxLevel = getMaxLevel(tree);
  const columnWidths = Array(maxLevel).fill(0); // 每列初始宽度为 0

  function traverse(node) {
    const { level, width, children } = node;

    if (level <= maxLevel) {
      // 计算非叶子节点宽度
      if (children && children.length > 0) {
        columnWidths[level - 1] = Math.max(columnWidths[level - 1], width || 0);
        children.forEach(traverse); // 递归处理子节点
      } else if (level === maxLevel) {
        // 如果是最大层级，直接计算宽度
        columnWidths[level - 1] = Math.max(columnWidths[level - 1], width || 0);
      }
    }
  }

  tree.forEach(traverse);
  return columnWidths;
};

const calculateSideRowHeights = (tree, result) => {
  tree.forEach((node) => {
    // 如果是叶子节点，记录其行高到对应的层级
    if (!node.children || node.children.length === 0) {
      result[node.field] = node.height;
    } else {
      // 如果是父节点，递归处理其子节点
      calculateSideRowHeights(node.children, result);
    }
  });
  return result;
};

const calculateHeaderColWidths = (tree, result) => {
  tree.forEach((node) => {
    // 如果是叶子节点，记录其行高到对应的层级
    if (!node.children || node.children.length === 0) {
      result[node.field] = node.width;
    } else {
      // 如果是父节点，递归处理其子节点
      calculateHeaderColWidths(node.children, result);
    }
  });
  return result;
};

const sideColWidths = calculateSideColumnWidths(rowsTreeHierarchy);
const sideRowHeights = calculateSideRowHeights(rowsTreeHierarchy, {});
const headerColWidths = calculateHeaderColWidths(customTree, {});

// 递归计算每列宽度
const calculateSideColWidth = (nodeField) => {
  return sideColWidths[nodeField.level];
};

/**
 * 计算节点高度
 * @param {Object} node 当前节点
 * @param {number} rowHeight 行高
 * @returns {number} 节点高度
 */
const calculateSideRowHeight = (nodeField) => {
  return sideRowHeights[nodeField.field];
};

class CustomColCell extends ColCell {
  drawTextShape() {
    let { x, y, width, height, value, isLeaf } = this.getMeta();
    const text = String(value || ""); // 获取单元格文本内容
    if (!isLeaf) {
      const textStyle = {
        fontSize: 12,
        fill: "#000",
        textAlign: "left",
        textBaseline: "middle", // 垂直基线
      };
      const fontSize = 12; // 字体大小
      const padding = 8; // 内边距
      const lineHeight = 12; // 行高
      const availableWidth = width - 2 * padding; // 可用绘制宽度
      // 分行逻辑：根据宽度动态分割文本
      const lines = splitTextIntoLines(text, availableWidth, fontSize);

      // 计算文本总高度并居中
      const totalTextHeight = lines.length * lineHeight;
      const startY = y + (height - totalTextHeight) / 2 + lineHeight / 2; // 起始 Y 坐标;

      // 绘制每行文本
      lines.forEach((line, lineIndex) => {
        let lineY = 0;
        if (lineIndex == 0) {
          lineY = startY + lineIndex * lineHeight; // 当前行的 Y 坐标
        } else {
          lineY = startY + lineIndex * lineHeight + 2; // 当前行的 Y 坐标
        }
        const totalChars = line.length; // 当前行字符数

        // 计算字符间距（分散对齐）
        const spaceBetween =
          totalChars > 1
            ? (availableWidth - textStyle.fontSize * totalChars) /
              (totalChars - 1)
            : 0;

        // 起始 X 坐标
        let startX = x + padding;

        // 绘制每个字符
        [...line].forEach((char, charIndex) => {
          const charX =
            startX + charIndex * (textStyle.fontSize + spaceBetween); // 当前字符 X 坐标
          const textShape = renderText({
            group: this,
            textShape: [this.textShape],
            style: {
              ...textStyle,
              x: charX,
              y: lineY,
              text: char,
            },
          });
          this.addTextShape(textShape);
        });
      });
    } else {
      // console.log("文本：", value, "宽度: ", width);
      // 叶子节点：竖排换行
      const padding = 8; // 内边距
      const textStyle = {
        fontSize: 12,
        fill: "#000",
        textAlign: "left",
        textBaseline: "middle", // 垂直基线
      };

      const lineHeight = textStyle.fontSize; // 行高
      const availableWidth = height - 2 * padding; // 可用高度
      const lines = splitTextIntoLines(
        value || "",
        availableWidth,
        textStyle.fontSize
      ); // 自动换行

      const startX =
        x + (width - lines.length * lineHeight) / 2 + lineHeight / 2; // 垂直居中
      lines.forEach((line, lineIndex) => {
        const totalChars = line.length;
        const spaceBetween =
          totalChars > 1
            ? (availableWidth - totalChars * textStyle.fontSize) /
              (totalChars - 1) // 分散对齐计算
            : 0;
        let startY = y + padding + 12 / 2; // 起始点
        [...line].forEach((char, charIndex) => {
          const charY =
            startY + charIndex * (textStyle.fontSize + spaceBetween); // 每个字符的 Y坐标
          renderText({
            group: this,
            style: {
              ...textStyle,
              y: charY,
              x: startX + lineIndex * lineHeight,
              text: char,
              textAlign: "center",
            },
          });
        });
      });
    }
  }
}

class CustomRowCell extends RowCell {
  /**
   * 根据下标计算数组中 >= index 的元素之和
   * @param {number[]} arr 数组
   * @param {number} index 下标
   * @returns {number} 元素之和
   */
  calculateSumFromIndex(arr, index) {
    if (index < 0 || index >= arr.length) {
      throw new Error("Index is out of bounds");
    }

    // 使用 slice 提取子数组并计算和
    return arr.slice(index).reduce((sum, num) => sum + num, 0);
  }

  calculateCellWidth(node, widths, level, maxLevel) {
    // 当前层级的默认宽度
    const currentWidth = widths[level] || 0;

    // 如果是叶子节点（没有 children 或到达最大层级），使用当前层级宽度
    if (level === maxLevel || !node.isLeaf) {
      return currentWidth;
    } else {
      return this.calculateSumFromIndex(widths, level);
    }
  }

  calculateCellHeight(node) {
    if (node.isLeaf) {
      // 如果是叶子节点，直接返回其高度
      return node.height || 0; // 默认高度为 0（防止未定义）
    } else {
      // 如果有子节点，递归计算子节点的高度总和
      const totalHeight = node.children.reduce((sum, child) => {
        return sum + this.calculateCellHeight(child);
      }, 0);
      return totalHeight + 4; //  这块补4是显示上有偏移4
    }
  }
  drawTextShape() {
    const { x, y, value, isLeaf, level } = this.meta;
    console.log(this.meta);
    //自身计算表旁宽度有问题，自定义实现
    const width = this.calculateCellWidth(
      this.meta,
      sideColWidths,
      level,
      this.meta.hierarchy.maxLevel
    );
    const height = this.calculateCellHeight(this.meta);
    const padding = 8; // 内边距
    const textStyle = {
      fontSize: 12,
      fill: "#000",
      textBaseline: "middle",
    };
    const lineHeight = textStyle.fontSize; // 行高

    if (!isLeaf) {
      const padding = 8; // 内边距
      const textStyle = {
        fontSize: 12,
        fill: "#000",
        textAlign: "left",
        textBaseline: "middle", // 垂直基线
      };

      const lineHeight = textStyle.fontSize; // 行高
      const availableWidth = height - 2 * padding; // 可用高度
      const lines = splitTextIntoLines(
        value || "",
        availableWidth,
        textStyle.fontSize
      ); // 自动换行

      const startX =
        x + (width - lines.length * lineHeight) / 2 + lineHeight / 2; // 垂直居中
      lines.forEach((line, lineIndex) => {
        const totalChars = line.length;
        const spaceBetween =
          totalChars > 1
            ? (availableWidth - totalChars * textStyle.fontSize) /
              (totalChars - 1) // 分散对齐计算
            : 0;
        let startY = y + padding + 12 / 2; // 起始点
        [...line].forEach((char, charIndex) => {
          const charY =
            startY + charIndex * (textStyle.fontSize + spaceBetween); // 每个字符的 Y坐标
          renderText({
            group: this,
            style: {
              ...textStyle,
              y: charY,
              x: startX + lineIndex * lineHeight,
              text: char,
              textAlign: "center",
            },
          });
        });
      });
    } else {
      //横向
      // 叶子节点：横排分散对齐并支持换行
      const availableWidth = width - 2 * padding; // 可用宽度
      const lines = splitTextIntoLines(
        value || "",
        availableWidth,
        textStyle.fontSize
      ); // 自动换行

      const startY =
        y + (height - lines.length * lineHeight) / 2 + lineHeight / 2; // 垂直居中
      lines.forEach((line, lineIndex) => {
        const totalChars = line.length;
        const spaceBetween =
          totalChars > 1
            ? (availableWidth - totalChars * textStyle.fontSize) /
              (totalChars - 1) // 分散对齐计算
            : 0;
        let startX = x + padding + 12 / 2; // 起始点
        [...line].forEach((char, charIndex) => {
          const charX =
            startX + charIndex * (textStyle.fontSize + spaceBetween); // 每个字符的 X 坐标
          renderText({
            group: this,
            style: {
              ...textStyle,
              x: charX,
              y: startY + lineIndex * lineHeight,
              text: char,
              textAlign: "left",
            },
          });
        });
      });
    }
  }
}

class CustomCornerHeader extends Group {
  header;

  backgroundShape;

  textShape;
  lineShape;
  constructor(header) {
    super({});
    this.header = header;
    this.initCornerHeader();
  }

  initCornerHeader() {
    this.initBg();
    this.initText();
  }

  initBg() {
    // const url ='../assets/logo.png';
    const { width, height } = this.header.getHeaderConfig();

    this.backgroundShape = this.header.appendChild(
      new GImage({
        style: {
          x: 0,
          y: 0,
          width,
          height,
          src: require("../assets/logo.png"),
        },
      })
    );
  }

  initText() {
    this.textShape = this.header.appendChild(
      new Text({
        zIndex: 100,
        style: {
          x: 50,
          y: 60,
          text: "corner in S2",
          fontFamily: "PingFang SC",
          fontSize: 20,
          fill: "green",
          stroke: "black",
        },
      })
    );
  }
}

const cellTheme = {
  cell: {
    backgroundColorOpacity: 0,
    // verticalBorderColorOpacity: 0,
    //horizontalBorderColorOpacity: 0,
  },
};
const BORDER_COLOR = "#e8eaec"; // 边框颜色
const COL_COLOR = "#f8f8f9"; //表头背景色
const BACK_COLOR = "#fff";
const HEADER_BACK_COLOR = "#fff"; //白色
const CELL_ACTIVE_BACK_COLOR = "#fff";

const customTheme = {
  // 画布背景底色
  background: {
    color: HEADER_BACK_COLOR,
  },
  // 空数据占位符
  //   empty: {
  //     icon: {
  //       fill: "#000",
  //       width: 64,
  //       height: 41,
  //       margin: {
  //         top: 0,
  //         right: 0,
  //         bottom: 24,
  //         left: 0,
  //       },
  //     },
  //     description: {
  //       fontFamily: FONT_FAMILY,
  //       fontSize: 12,
  //       fontWeight: "normal",
  //       fill: "#000",
  //       opacity: 1,
  //     },
  //   },

  //角头
  cornerCell: {
    cell: {
      //   backgroundColorOpacity: 0,
      horizontalBorderColor: BORDER_COLOR,
      verticalBorderColor: BORDER_COLOR,
      verticalBorderWidth: 1,
      horizontalBorderWidth: 1,
      //   backgroundColor: HEADER_BACK_COLOR,
    },
    // text: {
    //   fill: "#000",
    // },
    // bolderText: {
    //   fill: "#000",
    //   opacity: 0.4,
    // },
  },
  //分割线样式
  splitLine: {
    horizontalBorderColor: BORDER_COLOR,
    horizontalBorderColorOpacity: 1,
    horizontalBorderWidth: 1,
    verticalBorderColor: BORDER_COLOR,
    verticalBorderColorOpacity: 1,
    verticalBorderWidth: 1,
  },
  colCell: {
    cell: {
      horizontalBorderColor: BORDER_COLOR,
      verticalBorderColor: BORDER_COLOR,
      verticalBorderWidth: 1,
      horizontalBorderWidth: 1,
      backgroundColor: COL_COLOR,
      interactionState: {
        hover: {
          backgroundColor: COL_COLOR,
          //   backgroundOpacity: 1,
        },
        selected: {
          backgroundColor: COL_COLOR,
        },
      },
    },
    text: {
      fill: "#000",
    },
    bolderText: {
      fill: "#000",
    },
  },
  rowCell: {
    cell: {
      horizontalBorderColor: BORDER_COLOR,
      verticalBorderColor: BORDER_COLOR,
      verticalBorderWidth: 1,
      horizontalBorderWidth: 1,

      backgroundColor: HEADER_BACK_COLOR,
      // 交互态
      interactionState: {
        hover: {
          backgroundColor: "#fff",
          //   backgroundOpacity: 1,
        },
        selected: {
          backgroundColor: "#fff",
        },
      },
    },
    text: {
      fill: "#fff",
    },
    bolderText: {
      fill: "#fff",
      opacity: 0.4,
    },
  },
  dataCell: {
    cell: {
      interactionState: {
        hover: {
          backgroundColor: CELL_ACTIVE_BACK_COLOR,
          backgroundOpacity: 1,
        },
        hoverFocus: {
          backgroundColor: CELL_ACTIVE_BACK_COLOR,
          backgroundOpacity: 1,
          borderColor: "#fff",
        },
        selected: {
          backgroundColor: CELL_ACTIVE_BACK_COLOR,
          backgroundOpacity: 1,
        },
        unselected: {
          backgroundOpacity: 1,
          opacity: 1,
        },
        prepareSelect: {
          borderColor: CELL_ACTIVE_BACK_COLOR,
        },
      },
      horizontalBorderColor: BORDER_COLOR,
      verticalBorderColor: BORDER_COLOR,
      verticalBorderWidth: 1,
      horizontalBorderWidth: 1,
      backgroundColorOpacity: 1,
      backgroundColor: BACK_COLOR,
      crossBackgroundColor: BACK_COLOR,
    },
    text: {
      fill: "#000",
    },
  },
};

const data = [
  {
    beijing: "北京市",
    haidian: "海淀区",
    zizhuyuan: "紫竹院",
    "a-1": "财政教育经费投入",
    "a-1-1": "项目经费",
    bzhjs: "标准化建设",
    value: 12121,
  },
  {
    beijing: "北京市",
    haidian: "海淀区",
    zizhuyuan: "紫竹院",
    "a-1": "财政教育经费投入",
    "a-1-1": "项目经费",
    xxhjs: "信息化建设",
    value: 322,
  },
  {
    beijing: "北京市",
    haidian: "海淀区",
    zizhuyuan: "紫竹院",
    "a-1": "财政教育经费投入",
    "a-1-2": "基础拨款",
    value: 555,
  },
  {
    beijing: "北京市",
    haidian: "海淀区",
    zhongguancun: "中关村",
    "a-1": "财政教育经费投入",
    "a-1-1": "项目经费",
    bzhjs: "标准化建设",
    value: 12333,
  },
];

const s2DataConfig = {
  fields: {
    rows: rowsTreeHierarchy,
    columns: customTree,
    values: ["value"],
  },
  data,
};

const s2Options = {
  width: 800,
  height: 600,
  dataCell: (viewMeta, spreadsheet) => {
    return new CustomDataCell(viewMeta, spreadsheet);
  },
  rowCell: (node, spreadsheet, headerConfig) => {
    return new CustomRowCell(node, spreadsheet, headerConfig);
  },
  colCell: (node, spreadsheet, headerConfig) => {
    return new CustomColCell(node, spreadsheet, headerConfig);
  },
  cornerHeader: (header) => {
    return new CustomCornerHeader(header);
  },
  hierarchyType: "grid",
  style: {
    rowCell: {
      // 固定配置: 行头单元格 100px
      width: calculateSideColWidth,
      // 动态配置: 叶子节点 300px, 非叶子节点 200px
      height: calculateSideRowHeight,
    },
    colCell: {
      width: calculateHeaderColWidth,
      height: calculateHeaderRowHeight, // 动态设置高度
    },
  },
};

const container = ref(null);
let s2;
function getTable() {
  s2 = new PivotSheet(container.value, s2DataConfig, s2Options);

  s2.render();
  console.log(s2, "获取数据-----s2");
  s2.setTheme(customTheme);
}
onMounted(() => {
  getTable();
});

// S2 组件的引用
</script>

<style scoped>
/* 你的样式 */
.hello {
  margin: 0 300px;
}
</style>
